from rest_framework import serializers
from .models import Task, Category, Tag
from django.contrib.auth import get_user_model

User = get_user_model()

class TagSerializer(serializers.ModelSerializer):
    """
    标签序列化器
    用于标签的序列化和反序列化
    
    序列化字段：
    - id: 标签ID
    - name: 标签名称
    - color: 标签颜色
    """
    class Meta:
        model = Tag
        fields = ['id', 'name', 'color']

class CategorySerializer(serializers.ModelSerializer):
    """
    分类序列化器
    用于分类的序列化和反序列化
    
    序列化字段：
    - id: 分类ID
    - name: 分类名称
    - description: 分类描述
    """
    class Meta:# Meat类是序列化器的内部类，用来提供元数据信息
        model = Category# 表明该序列化器宇Category模型关联
        fields = ['id', 'name', 'description']# 指定了序列化器中包含的字段

class TaskSerializer(serializers.ModelSerializer):
    """
    任务序列化器
    用于任务的序列化和反序列化
    
    序列化字段：
    - id: 任务ID
    - title: 任务标题
    - description: 任务描述
    - due_date: 截止日期
    - priority: 优先级
    - status: 状态
    - category: 分类信息（只读）
    - category_id: 分类ID（只写）
    - tags: 标签信息（只读）
    - tag_ids: 标签ID列表（只写）
    - created_at: 创建时间
    - updated_at: 更新时间
    - completed_at: 完成时间
    """
    # 只读字段，用于显示分类的详细信息，序列化的时候使用
    category = CategorySerializer(read_only=True)
    # 只写字段，用于接收分类ID，反序列化的时候使用
    category_id = serializers.PrimaryKeyRelatedField(
        queryset=Category.objects.all(),#用户传递的必须是category中存在的
        source='category',# category_id 字段的值会被映射到任务模型的 category 外键字段
        write_only=True,
        required=False
    )
    # 只读字段，用于显示标签的详细信息
    tags = TagSerializer(many=True, read_only=True)
    # 只写字段，用于接收标签ID列表
    tag_ids = serializers.PrimaryKeyRelatedField(
        queryset=Tag.objects.all(),
        source='tags',
        write_only=True,
        many=True,
        required=False
    )

    class Meta:
        model = Task
        fields = [
            'id', 'title', 'description', 'due_date', 'priority',
            'status', 'category', 'category_id', 'tags', 'tag_ids',
            'created_at', 'updated_at', 'completed_at'
        ]
        read_only_fields = ['created_by', 'created_at', 'updated_at', 'completed_at']

    def create(self, validated_data):
        """
        创建任务时的处理
        将当前请求的用户设置为任务创建者
        """
        # 从上下文中获取请求对象
        request = self.context.get('request')
        # 设置当前登录用户为任务创建者
        if request and hasattr(request, 'user'):
            validated_data['created_by'] = request.user
        return super().create(validated_data)

    def update(self, instance, validated_data):
        """
        更新任务时的处理
        1. 处理分类的更新
        2. 处理标签的更新
        3. 更新其他字段
        4. 保存更新后的实例
        """
        # 处理category的更新
        if 'category' in validated_data:
            instance.category = validated_data.pop('category')
        
        # 处理tags的更新
        if 'tags' in validated_data:
            instance.tags.set(validated_data.pop('tags'))# 用于批量设置关联对象。
        
        # 更新其他字段
        for attr, value in validated_data.items():
            setattr(instance, attr, value)
        
        instance.save()
        return instance 